/*************************************************
 * ThinkJot V2
 * Author: Jeswin P. (jeswin@process64.com)
 * Website: http://www.process64.com/thinkjot/
 * This code is distributed under the terms of the
 * Apache License, Version 2.0.
 * **********************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;

using ThinkJot.Core.Utils;
using ThinkJot.Core.Blogs.Providers;
using ThinkJot.Core.Configuration;
namespace ThinkJot.Core.Blogs
{
    [Serializable]
    public class BlogEntry : IComparable<BlogEntry>
    {        
        public const int NormalType = 1;
        public const int ArticleType = 2;

        public BlogEntry()
        {
            uniqueId = Guid.NewGuid();
            time = DateTime.Now.ToUniversalTime();
            excludeFromList = false;
        }

        long id;
        public long Id
        {
            get { return id; }
            set { id = value; }
        }

        Guid uniqueId;
        public Guid UniqueId
        {
            get { return uniqueId; }
            set { uniqueId = value; }
        }

        int entryType = NormalType;
        public int EntryType
        {
            get { return entryType; }
            set { entryType = value; }
        }

        string content = "";
        public string Content
        {
            get 
            {
                return content; 
            }
            set 
            {
                content = value;
            }
        }

        string title = "";
        public string Title
        {
            get 
            {
                return title; 
            }
            set { title = value; }
        }

        string description = "";
        public string Description
        {
            get 
            {
                return description;
            }
            set 
            {
                description = value;
            }
        }

        string author = "";
        public string Author
        {
            get 
            {
                return author;
            }
            set { author = value; }
        }

        DateTime time;
        public DateTime Time
        {
            get { return time; }
            set 
            {
                time = value.ToUniversalTime();
            }
        }

        DateTime modifiedTime;
        public DateTime ModifiedTime
        {
            get { return modifiedTime; }
            set 
            {
                modifiedTime = value.ToUniversalTime();
            }
        }

        bool allowComments;
        public bool AllowComments
        {
            get { return allowComments; }
            set { allowComments = value; }
        }

        bool commentsClosed = false;
        public bool CommentsClosed
        {
            get { return commentsClosed; }
            set { commentsClosed = value; }
        }

        int disableCommentsAfterDays = -1;
        public int DisableCommentsAfterDays
        {
            get { return disableCommentsAfterDays; }
            set { disableCommentsAfterDays = value; }
        }


        bool syndicate; //show in RSS
        public bool Syndicate
        {
            get { return syndicate; }
            set { syndicate = value; }
        }

        bool publish; //Whether the article is ready for publishing
        public bool Publish
        {
            get { return publish; }
            set { publish = value; }
        }

        bool excludeFromList;
        public bool ExcludeFromList
        {
            get { return excludeFromList; }
            set { excludeFromList = value; }
        }

        List<int> categoryIds = new List<int>();
        public List<int> CategoryIds
        {
            get { return categoryIds; }
            set { categoryIds = value; }
        }

        List<string> tags = new List<string>();
        public List<string> Tags
        {
            get { return tags; }
            set { tags = value; }
        }

        List<Comment> comments = new List<Comment>();
        public List<Comment> Comments
        {
            get { return comments; }
            set { comments = value; }
        }

        //The blog-entry class could be extended with any data
        //using this list.
        List<DataTag> dataTags = new List<DataTag>();
        public List<DataTag> DataTags
        {
            get { return dataTags; }
            set { dataTags = value; }
        }

        /// <summary>
        /// This method will load a blog entry with all the comments.
        /// </summary>
        /// <param name="blogName"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        public void Save(string blogName)
        {
            BlogEntryDP dataProvider = BlogDataProvider.GetBlogEntryProvider();
            dataProvider.SaveBlogEntry(this, blogName);

            if (publish)
            {
                FeedsDP feedsDP = BlogDataProvider.GetFeedsDP();
                feedsDP.UpdateFeeds(blogName); 
                
                PingTrackers(blogName);
            }
        }

        public void Update(string blogName)
        {
            BlogEntryDP dataProvider = BlogDataProvider.GetBlogEntryProvider();
            dataProvider.UpdateBlogEntry(this, blogName);

            if (publish)
            {
                FeedsDP feedsDP = BlogDataProvider.GetFeedsDP();
                feedsDP.UpdateFeeds(blogName);
                
                PingTrackers(blogName);
            }
        }

        public static List<BlogEntry> GetAllBlogEntries(string blogName)
        {
            BlogEntryDP dataProvider = BlogDataProvider.GetBlogEntryProvider();
            return dataProvider.GetAllBlogEntries(blogName);
        }

        public static List<BlogEntry> GetAllBlogEntriesAfter(string blogName, DateTime afterWhen)
        {
            BlogEntryDP dataProvider = BlogDataProvider.GetBlogEntryProvider();
            return dataProvider.GetAllBlogEntriesAfter(afterWhen, blogName);
        }

        public static List<BlogEntry> GetLastNormalTypeEntries(int count, bool showUnpublished, string blogName)
        {
            BlogEntryDP dataProvider = BlogDataProvider.GetBlogEntryProvider();
            return dataProvider.GetLastNormalTypeEntries(count, showUnpublished, blogName);
        }

        public static List<BlogEntry> SearchBlogEntries(string blogName, string[] keywords)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.SearchBlogEntries(blogName, keywords);
        }

        public static string SaveFile(string fileName, byte[] fileContent, string blogName, bool overwrite)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.SaveFile(fileName, fileContent, blogName, overwrite);
        }

        public static BlogEntry GetBlogEntry(Guid entryId, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetBlogEntry(entryId, blogName);
        }

        public static BlogEntry GetBlogEntryByTitle(string title, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetBlogEntryByTitle(title, blogName);
        }

        public static List<BlogEntry> GetEntriesForMonth(int month, int year, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetEntriesForMonth(month, year, blogName);
        }

        public static List<BlogEntry> GetEntriesInCategory(int categoryId, int start, int count, out int totalItems, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetEntriesInCategory(categoryId, start, count, out totalItems, blogName);
        }

        public static List<BlogEntry> GetEntriesByTag(string tag, int start, int count, out int totalItems, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetEntriesByTag(tag, start, count, out totalItems, blogName);
        }

        public static List<BlogEntrySummary> GetLastEntriesSummary(int count, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetLastEntriesSummary(count, blogName);
        }

        public static void DeleteEntry(Guid entryId, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            provider.DeleteBlogEntry(entryId, blogName);

            //refresh the feeds.
            FeedsDP feedsDP = BlogDataProvider.GetFeedsDP();
            feedsDP.UpdateFeeds(blogName);
        }

        public static List<BlogEntry> GetBlogEntries(List<Guid> ids, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetBlogEntries(ids, blogName);
        }

        public static List<BlogEntry> GetDeletedEntries(string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetDeletedEntries(blogName);
        }

        public static void Undelete(Guid entryId, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            provider.Undelete(entryId, blogName);
        }

        public static BlogEntry GetDeletedBlogEntry(Guid blogEntryId, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetDeletedBlogEntry(blogEntryId, blogName);
        }

        public static Guid GetEntryIdForTitle(string title, string blogName)
        {
            BlogEntryDP provider = BlogDataProvider.GetBlogEntryProvider();
            return provider.GetEntryIdForTitle(title, blogName);
        }

        public static string GetPermaLink(Guid entryId, string blogName)
        {
            PathUtility pathUtil = new PathUtility();            
            return pathUtil.CombineUrls(pathUtil.GetMappedBlogUrl(blogName), "default.aspx?function=DisplayItem&entryGuid=" + entryId.ToString());
        }

        private void PingTrackers(string blogName)
        {
            BlogConfig config = SystemConfiguration.GetConfig().Blogs.GetBlogConfig(blogName);
            if (config.PingWeblogUpdateTrackers)
                UpdatePingInfo.PingAll(blogName);
        }

        #region IComparable<BlogEntry> Members

        public int CompareTo(BlogEntry other)
        {
            if (other.Time > Time) return -1;
            if (other.time < Time) return 1;
            return 0;
        }
        #endregion
    }
}
